<!DOCTYPE html>
<html>
<head>
	<title>面向对象的继承</title>
</head>
<body>
<script>
//继承


//【原型链】
// function SuperType() {
// 	this.property = true;
// }

// SuperType.prototype.getSuperValue = function() {
// 	return this.property;
// };

// function SubType() {
// 	this.subproperty = false;
// }

// SubType.prototype = new SuperType();
// SubType.prototype.constructor = SubType;
// SubType.prototype.getSubValue = function() {
// 	return this.subproperty;
// };

// // console.log(SubType.prototype.constructor);
// var instance = new SubType();
// console.log(instance.getSuperValue());

//原型链缺陷
// function SuperType() {
// 	this.colors = ['red', 'blue', 'green'];
// }

// function SubType() {}

// SubType.prototype = new SuperType();

// var instanceA = new SubType();
// instanceA.colors.push('black');
// console.log(instanceA.colors);

// var instanceB = new SubType();
// console.log(instanceB.colors);
//【原型链】



//【借用构造函数（经典继承）】
// function SuperType(name) {
// 	this.name = name;
// 	this.colors = ['red', 'blue', 'green'];
// }

// function SubType() {
// 	SuperType.call(this, 'Daryl');
// }

// var instanceA = new SubType();
// instanceA.colors.push('black');
// console.log(instanceA.colors);

// var instanceB = new SubType();
// console.log(instanceB.colors);

//借用构造函数问题
//方法都是在子类中创建的，函数无法复用

//【借用构造函数】



//【组合继承（伪经典继承）】
// function SuperType(name) {
// 	this.name = name;
// 	this.colors = ['red', 'blue', 'green'];
// }

// SuperType.prototype.sayName = function() {
// 	console.log(this.name);
// };

// function SubType(name, age) {
// 	SuperType.call(this, name); //第二次调用 SuperType()
// 	this.age = age;
// }

// SubType.prototype = new SuperType(); //第一次调用 SuperType()
// // console.log(SubType.prototype.constructor); //SuperType
// SubType.prototype.constructor = SubType;
// SubType.prototype.sayAge = function() {
// 	console.log(this.age);
// };

// var instanceA = new SubType('AAA', 29);
// instanceA.colors.push('black');
// console.log(instanceA.colors);
// instanceA.sayName();
// instanceA.sayAge();

// var instanceB = new SubType('BBB', 27);
// console.log(instanceB.colors);
// instanceB.sayName();
// instanceB.sayAge();

//组合继承问题
//组合继承融合了原型链与借用构造函数的优点，避免了二者的缺陷，是最常用的继承模式。
//由于调用了两次 SuperType，会分别在 SubType 的原型对象和实例对象上分别创建属性。

// console.log(SubType.prototype.hasOwnProperty('name')); //instanceA.name & instanceA.__proto__.name

//【组合继承】



//【原型式继承】
function object(o) {
	function F() {}
	F.prototype = o;
	return new F();
}

var person = {
	name: 'ABC',
	friends: ['Shelby', 'Court', 'Van']
};

var personA = object(person);
personA.name = 'AAA';
personA.friends.push('Rob');

var personB = object(person);
personB.name = 'BBB';
personB.friends.push('Barbie');

console.log(person.friends);
console.log(personA.friends);

//ES5实现原型式继承
// var person = {
// 	name: 'ABC',
// 	friends: ['Shelby', 'Court', 'Van']
// };

// var personA = Object.create(person);
// personA.name = 'AAA';
// personA.friends.push('Rob');

// var personB = Object.create(person);
// personB.name = 'BBB';
// personB.friends.push('Barbie');

// console.log(person.friends);

//原型式继承问题
//在没有必要兴师动众地创建构造函数，而只想让一个对象与另一个对象保持类似的情况下，原型式继承是完全可以胜任的。
//【原型式继承】



//【寄生式继承】
// function createAnother(original) {
// 	var clone = Object.create(original);
// 	clone.sayHi = function() {
// 		console.log('hi');
// 	};
// 	return clone;
// }

// var person = {
// 	name: 'abc',
// 	friends: ['Shelby', 'Court', 'Van']
// };

// var anotherPerson = createAnother(person);
// anotherPerson.sayHi();

//寄生式继承问题
//在主要考虑对象而不是自定义类型和构造函数的情况下，寄生式继承也是一种有用的模式。
//使用寄生式继承来为对象添加函数，会由于不能做到函数复用而降低效率；这一点与借用构造函数类似。

//【寄生式继承】



//【寄生组合式继承】
// function inheritPrototype(subType, superType) {
// 	var prototype = Object.create(superType.prototype);
// 	prototype.constructor = subType;
// 	subType.prototype = prototype;
// }

// function SuperType(name) {
// 	this.name = name;
// 	this.colors = ['red', 'blue', 'green'];
// }

// SuperType.prototype.sayName = function() {
// 	console.log(this.name);
// };

// function SubType(name, age) {
// 	SuperType.call(this, name);
// 	this.age = age;
// }

// inheritPrototype(SubType, SuperType);

// SubType.prototype.sayAge = function() {
// 	console.log(this.age);
// };

// var instanceA = new SubType('aaa', 26);

// console.log(SubType.prototype.hasOwnProperty('name'));

//寄生组合式继承问题
//上例的高效率体现在它只调用了一次 SuperType 构造函数，并且因此避免了在 SubType.prototype 上创建不必要的属性。寄生组合式继承是引用类型最理想的继承范式。

//【寄生组合式继承】

</script>
</body>
</html>